package com.cruise.game.service.impl.admin;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cruise.game.common.api.ApiException;
import com.cruise.game.common.constants.CacheConstants;
import com.cruise.game.common.utils.RedisUtils;
import com.cruise.game.mapper.GameCategoryMapper;
import com.cruise.game.mapper.GameServiceMapper;
import com.cruise.game.model.entity.GameCategory;
import com.cruise.game.model.param.admin.GameCategoryCreateParam;
import com.cruise.game.model.param.admin.GameCategoryUpdateParam;
import com.cruise.game.model.vo.admin.GameCategoryVO;
import com.cruise.game.model.vo.common.PageResult;
import com.cruise.game.service.admin.AdminCategoryService;
import com.cruise.game.service.common.UploadService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 管理员游戏分类服务实现
 * 
 * @author cruise
 * @date 2025-02-28
 */
@Slf4j
@Service
public class AdminCategoryServiceImpl implements AdminCategoryService {

    @Resource
    private GameCategoryMapper gameCategoryMapper;

    @Resource
    private GameServiceMapper gameServiceMapper;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private UploadService uploadService;

    @Override
    public PageResult<GameCategoryVO> getCategoryList(String status, Integer page, Integer pageSize) {
        // 构建查询条件
        LambdaQueryWrapper<GameCategory> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(status)) {
            queryWrapper.eq(GameCategory::getStatus, status);
        }
        queryWrapper.orderByDesc(GameCategory::getCreatedAt);
        
        // 分页查询
        IPage<GameCategory> categoryPage = gameCategoryMapper.selectPage(new Page<>(page, pageSize), queryWrapper);
        
        // 转换为VO
        List<GameCategoryVO> categoryVOs = new ArrayList<>();
        for (GameCategory category : categoryPage.getRecords()) {
            GameCategoryVO vo = new GameCategoryVO();
            BeanUtils.copyProperties(category, vo);
            
            // 查询服务数量
            Integer serviceCount = gameServiceMapper.countByCategoryId(category.getId());
            vo.setServiceCount(serviceCount);
            
            categoryVOs.add(vo);
        }
        
        // 构建分页结果
        return PageResult.of(categoryVOs, categoryPage.getTotal(), page, pageSize);
    }

    @Override
    public GameCategoryVO getCategoryDetail(Long id) {
        // 查询游戏分类信息
        GameCategory category = gameCategoryMapper.selectById(id);
        if (category == null) {
            throw new ApiException("游戏分类不存在");
        }
        
        // 构建游戏分类VO
        GameCategoryVO categoryVO = new GameCategoryVO();
        BeanUtils.copyProperties(category, categoryVO);
        
        // 查询服务数量
        Integer serviceCount = gameServiceMapper.countByCategoryId(category.getId());
        categoryVO.setServiceCount(serviceCount);
        
        return categoryVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createCategory(GameCategoryCreateParam param) {
        // 验证分类名称是否存在
        GameCategory existCategory = gameCategoryMapper.selectByName(param.getName());
        if (existCategory != null) {
            throw new ApiException("分类名称已存在");
        }
        
        // 构建游戏分类对象
        GameCategory category = new GameCategory();
        BeanUtils.copyProperties(param, category);
        
        // 设置状态
        if (StringUtils.isBlank(category.getStatus())) {
            category.setStatus("active");
        }
        
        // 设置时间
        LocalDateTime now = LocalDateTime.now();
        category.setCreatedAt(now);
        category.setUpdatedAt(now);
        
        // 保存游戏分类
        gameCategoryMapper.insert(category);
        
        // 清除缓存
        redisUtils.del(CacheConstants.GAME_CATEGORY_LIST_CACHE);
        redisUtils.del(CacheConstants.HOME_DATA_CACHE);
        
        return category.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategory(Long id, GameCategoryUpdateParam param) {
        // 查询游戏分类信息
        GameCategory category = gameCategoryMapper.selectById(id);
        if (category == null) {
            throw new ApiException("游戏分类不存在");
        }
        
        // 验证分类名称是否存在
        if (StringUtils.isNotBlank(param.getName()) && !param.getName().equals(category.getName())) {
            GameCategory existCategory = gameCategoryMapper.selectByName(param.getName());
            if (existCategory != null) {
                throw new ApiException("分类名称已存在");
            }
        }
        
        // 旧图标URL
        String oldIconUrl = category.getIconUrl();
        
        // 更新游戏分类
        if (StringUtils.isNotBlank(param.getName())) {
            category.setName(param.getName());
        }
        if (StringUtils.isNotBlank(param.getIconUrl())) {
            category.setIconUrl(param.getIconUrl());
        }
        if (param.getDescription() != null) {
            category.setDescription(param.getDescription());
        }
        if (StringUtils.isNotBlank(param.getStatus())) {
            category.setStatus(param.getStatus());
        }
        
        // 设置更新时间
        category.setUpdatedAt(LocalDateTime.now());
        
        // 更新游戏分类
        boolean success = gameCategoryMapper.updateById(category) > 0;
        
        // 清除缓存
        if (success) {
            redisUtils.del(CacheConstants.GAME_CATEGORY_LIST_CACHE);
            redisUtils.del(CacheConstants.GAME_CATEGORY_CACHE_PREFIX + id);
            redisUtils.del(CacheConstants.HOME_DATA_CACHE);
            
            // 删除旧图标
            if (StringUtils.isNotBlank(oldIconUrl) && StringUtils.isNotBlank(param.getIconUrl()) && !oldIconUrl.equals(param.getIconUrl())) {
                try {
                    uploadService.deleteFile(oldIconUrl);
                } catch (Exception e) {
                    log.error("删除旧游戏分类图标失败: {}", e.getMessage(), e);
                }
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCategory(Long id) {
        // 查询游戏分类信息
        GameCategory category = gameCategoryMapper.selectById(id);
        if (category == null) {
            throw new ApiException("游戏分类不存在");
        }
        
        // 验证是否有关联的服务
        Integer serviceCount = gameServiceMapper.countByCategoryId(id);
        if (serviceCount > 0) {
            throw new ApiException("该分类下有关联的服务，无法删除");
        }
        
        // 游戏分类图标URL
        String iconUrl = category.getIconUrl();
        
        // 删除游戏分类
        boolean success = gameCategoryMapper.deleteById(id) > 0;
        
        // 清除缓存
        if (success) {
            redisUtils.del(CacheConstants.GAME_CATEGORY_LIST_CACHE);
            redisUtils.del(CacheConstants.GAME_CATEGORY_CACHE_PREFIX + id);
            redisUtils.del(CacheConstants.HOME_DATA_CACHE);
            
            // 删除图标
            if (StringUtils.isNotBlank(iconUrl)) {
                try {
                    uploadService.deleteFile(iconUrl);
                } catch (Exception e) {
                    log.error("删除游戏分类图标失败: {}", e.getMessage(), e);
                }
            }
        }
        
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCategoryStatus(Long id, String status) {
        // 查询游戏分类信息
        GameCategory category = gameCategoryMapper.selectById(id);
        if (category == null) {
            throw new ApiException("游戏分类不存在");
        }
        
        // 更新状态
        boolean success = gameCategoryMapper.updateStatus(id, status) > 0;
        
        // 清除缓存
        if (success) {
            redisUtils.del(CacheConstants.GAME_CATEGORY_LIST_CACHE);
            redisUtils.del(CacheConstants.GAME_CATEGORY_CACHE_PREFIX + id);
            redisUtils.del(CacheConstants.HOME_DATA_CACHE);
        }
        
        return success;
    }
}
